console.log("KJSU Runing")
import fs from "node:fs";
function saveFile(path, str) {
  console.log("Save File:", path);
  try {
    fs.writeFileSync(path, str);
  } catch (e) {
    console.log(e);
  }
}
function readFile(path) {
  try {
    return fs.readFileSync(path, "utf8");
  } catch (e) {
    console.log(e);
  }
}

function deleteFile(path) {
  try {
    fs.rmSync(path);
  } catch (e) {
    console.log("Delete File Error ", path);
    console.log(e);
  }
}
function compareLists(oldList, newList) {
  const oldMap = new Map();
  const newMap = new Map();

  // Fill the oldMap with the old list
  oldList.forEach(entry => {
    oldMap.set(entry.path, entry);
  });

  // Fill the newMap with the new list and check for updates
  const updated = [];
  const deleted = [];
  const added = [];

  newList.forEach(entry => {
    newMap.set(entry.path, entry);
    const oldEntry = oldMap.get(entry.path);
    if (oldEntry) {
      if (oldEntry.mtime !== entry.mtime && oldEntry.size !== entry.size) {
        updated.push(entry);
      }
      oldMap.delete(entry.path); // Remove from oldMap to find deletions later
    } else {
      added.push(entry);
    }
  });

  // The remaining items in oldMap are deletions
  oldMap.forEach(entry => {
    deleted.push(entry);
  });

  return { updated, deleted, added };
}

function printFileList(name, list) {
  console.log("\x1b[91m[kjsu]\x1b[0m File List", name, list.length);
  list.forEach(entry => {
    console.log(`${entry.path} - ${entry.mtime} - ${entry.size}`);
  });
}


function downloadFile(url, path) {
  console.log("Download:", url, " => ", path)
  fetch(url).then(res => res.text()).then(text => {
    saveFile(path, text)
  }).catch(e => {
    console.log(e)
  })
}

function buildFileTree(files) {
  const root = {
    path: '/',
    name: '文库',
    type: 'dir',
    items: []
  };

  files.forEach(file => {
    const parts = file.path.split('/');
    let current = root;

    parts.forEach((part, index) => {
      if (index === parts.length - 1) {
        part = part.slice(0, -3)
      }

      let found = current.items.find(item => item.name === part);

      if (!found) {
        found = {
          path: parts.slice(0, index + 1).join('/') + (index < parts.length - 1 ? '/' : ''),
          name: part,
          type: index === parts.length - 1 ? 'file' : 'dir',
          ...(index === parts.length - 1 ? { mtime: file.mtime, size: file.size } : { items: [] })
        };
        current.items.push(found);
      }

      current = found;
    });
  });

  return root;
}

function extractContent(filename) {
  try {
    // Read the file content
    const content = fs.readFileSync(filename, 'utf8');

    // Regular expressions to match YAML front matter and Markdown content
    const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n/;
    const markdownRegex = /^---\s*\n[\s\S]*?\n---\s*\n([\s\S]*)/;

    // Extract YAML and Markdown content using the regular expressions
    const yamlMatch = content.match(yamlRegex);
    const markdownMatch = content.match(markdownRegex);

    // Handle cases where matches are not found
    const yamlContent = yamlMatch ? yamlMatch[1] : "";
    const markdownContent = markdownMatch ? markdownMatch[1] : content;

    // Return the extracted content
    return {
      yamlContent: yamlContent,
      markdownContent: markdownContent,
    };
  } catch (err) {
    // Handle the error
    console.log(filename)
    throw new Error(err);
  }
}

function extractWikiLinksAndTags(content) {
  // Regular expression to match Wiki links
  const wikiLinkRegex = /\[\[([^|\]]+)(?:\|([^|\]]+))?\]\]/g;
  // Regular expression to match tags
  const tagRegex = /(^#(\w+)\b|[\s|\n]#(\w+))\b/g;

  // Find all Wiki link matches
  let wikiLinkMatches = content.matchAll(wikiLinkRegex);
  // Find all tag matches
  let tagMatches = content.matchAll(tagRegex);

  // Array to hold the extracted Wiki links
  let wikiLinks = [];
  // Array to hold the extracted tags
  let tags = [];

  // Process Wiki link matches
  for (let match of wikiLinkMatches) {
    let link = match[1];
    let description = match[2] ? match[2] : link; // Default description to the link itself if not provided
    wikiLinks.push({ link: link, description: description });
  }

  // Process tag matches
  for (let match of tagMatches) {
    let tag = match[1].trim();
    tag = tag.startsWith('#') ? tag.slice(1) : tag;
    tags.push(tag);
  }

  return { wikiLinks, tags };
}


fetch("https://note.ftls.xyz/help/kkbt-sum.md").then(res => res.json()).then(sumNow => {
  // save file
  saveFile("content/kkbt/sum.json", JSON.stringify(sumNow))
  let sumOld = JSON.parse(readFile("content/kkbt/sum.old.json"));
  let { updated, deleted, added } = compareLists(sumOld, sumNow);
  printFileList("Added", added)
  printFileList("Deleted", deleted)
  printFileList("Updated", updated)

  let fileList = [];

  added.forEach(entry => {
    fileList.push(entry)
  })
  updated.forEach(entry => {
    fileList.push(entry)
  })

  // 执行下载 单线程
  console.log("Download:", fileList.length)
  fileList.forEach(entry => {
    downloadFile("https://note.ftls.xyz/" + encodeURIComponent(entry.path), `content/${entry.path}`)
  })
  console.log("Del:", deleted.length)
  deleted.forEach(entry => {
    deleteFile(`content/${entry.path}`)
  })
  console.log("Download Finish")

  let sumMd = "**目录:**\n{{< tree >}}\n**索引列表:**\n";
  sumNow.forEach(entry => {
    sumMd += `[[${entry.path.slice(0, -3)}]]\n`
  })
  sumMd += "\n构建于 " + new Date();

  saveFile("content/kkbt/sum.md", sumMd)

  // root := Node{Path: "/", Type: "dir", Name: "文库"}
  // 生成文件列表树
  const tree = buildFileTree(sumNow);
  saveFile("data/tree.json", JSON.stringify(tree, null, 2))

  // 生成 markdown wiki link map
  let filesInfo = [];
  const other = [{ path: "kkbt/_index.md", mtime: new Date(), size: 0 }, { path: "kkbt/sum.md", mtime: new Date(), size: 0 }]
  const allNow = [...other, ...sumNow]
  allNow.forEach(entry => {
    const { yamlContent, markdownContent } = extractContent(`content/${entry.path}`);
    const { wikiLinks, tags } = extractWikiLinksAndTags(markdownContent);
    filesInfo.push({
      path: entry.path,
      wikiLinks: wikiLinks,
      tags: tags,
    })
  })
  const mapList = [];
  filesInfo.forEach(it => {
    it.wikiLinks.forEach(wikiLink => {
      let link1 = it.path.replace(/\.md$/, '').replace(/\/_index$/, '');
      mapList.push([link1, wikiLink.link]);
    });
  });

  saveFile("data/map.json", JSON.stringify(mapList, null, 2))

  console.log("END")
})